/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package client;

/**
 *
 * @author Welcome
 */
import java.applet.*;
import java.awt.*;
import java.net.*;
import java.util.Vector;

class clientwindow extends Frame implements Runnable
{
	static final int PLAYER1 = 1;
  	static final int PLAYER2 = 2;
	private gameclient gclient = new gameclient();
  	private String text, opponent_temp;
  	private Vector id_vector = new Vector(1,1);
  	private boolean game_on = false;
	private boolean move_received = false;
  	private boolean finish = false;
 	private boolean challenged = false;
   	private int player = PLAYER1;		// who is player 1
  	private int other_player = PLAYER2;	// who is player 2
  	private int opponent_id;		// store id of opponent
  	private int personal_id;		// store your id
  	private String nextMoveBuffer;	// store next move made

   	private URL base;
	private int port;
   	private Thread thread;
	private int battle_id;

 	private Label userlabel;
	private Label userlabel2;
	private Label userlabel3;
	private Panel mypanel;
	private String Username;
    	private List user_list;
    	private TextArea textArea;
    	private TextField textField;
	private Color bk_color;
	private Color fg_color;
	private Color bx_color;
  	private boolean statusflag = false;
	private Image gameimage;
	private graphicpanel gp;
	private game mygame;    	// User fills this class in
	Applet myapplet;

clientwindow(Applet theapplet, URL base_url, int theport, String User, Image image)
{
 		myapplet = theapplet;
 		base = base_url;
  		port = theport;
		Username = User;
		gameimage = image;
		int framewidth = 410;
		int frameheight = 540;

		bk_color = new Color(90,90,90);
		fg_color = new Color(255,206,140);
		bx_color = new Color(2,29,15);

  		this.setSize(framewidth,frameheight);
  		this.setTitle("Client-Server Communications Window");
		this.setBackground(Color.black);
		this.setForeground(Color.black);
		this.setLayout(null);

		gp = new graphicpanel(gameimage);
		gp.setLocation(60, 30);
		gp.setSize(300,100);
		this.add(gp);

	//	userlabel = new Label();
	//	userlabel.setText(" " + User);
    	//	userlabel.setFont(new Font("Helvetica",Font.PLAIN,16));
	//	userlabel.setForeground(Color.white);
	//	userlabel.setBackground(Color.black);
	//	userlabel.setLocation(framewidth / 4, 70);
	//	userlabel.setSize(100,30);
	//	this.add(userlabel);

		mypanel = new Panel();
		mypanel.setLayout(new BorderLayout());

		userlabel2 = new Label();
		userlabel2.setText("      List of Players Waiting -> to Play Double Click One");
    		userlabel2.setFont(new Font("Helvetica",Font.PLAIN,16));
		userlabel2.setForeground(Color.white);
		userlabel2.setBackground(Color.black);
		mypanel.add(userlabel2, BorderLayout.NORTH);

   		user_list=new List();
		user_list.setBackground(Color.blue);
		user_list.setForeground(Color.white);
    		mypanel.add(user_list, BorderLayout.CENTER);

		mypanel.setLocation(4, 135);
		mypanel.setSize(framewidth-5,200);
		this.add(mypanel);

		userlabel3= new Label();
		userlabel3.setText("  Type in red box below & hit c/r to send msg to Opponent");
    		userlabel3.setFont(new Font("Helvetica",Font.PLAIN,16));
		userlabel3.setForeground(Color.white);
		userlabel3.setBackground(Color.black);
		userlabel3.setLocation(1, 340);
		userlabel3.setSize(framewidth,30);
		this.add(userlabel3);

		textField=new TextField(41);
    		textField.setFont(new Font("Helvetica",Font.PLAIN,16));
		textField.setBackground(Color.red);
		textField.setForeground(Color.white);
    		textField.setLocation(1, 370);
		textField.setSize(framewidth,30);
		this.add(textField);

		textArea=new TextArea(41,8);
    		textArea.setFont(new Font("Helvetica",Font.PLAIN,14));
		textArea.setBackground(Color.white);
		textArea.setForeground(Color.black);
		textArea.setEditable(false);
		textArea.setLocation(1, 400);
		textArea.setSize(framewidth,100);

    		this.add(textArea);

        	this.setSize(framewidth, frameheight);
 		this.show();
		this.start(); // start this thread via contructor
}

// gets the thread going
public void start()
{
	System.out.println("starting thread");
  	thread = new Thread(this,"main");
  	thread.start();
}

public void run()
{
 	System.out.println("RUN ing thread");

     	display("Trying to connect to socket...\n");
	System.out.println("server port is " + port);
	System.out.println("URL is " + base.getHost());
     	statusflag = gclient.connect(base.getHost(),port);
       if (!statusflag)
	{
     	  	display("Unable to to connect, gameServer is probably down...\n");
	}
    	else
	{
 		display ("Connected to Socket!!!\n");
     		String textstream = Username;
      		//gclient.send_stream("!!name!!" +textstream);
                gclient.send_stream("!!name!!" +" ngay mai khong co gio");
		System.out.println("gclient.send_stream username sent is " + textstream);
    	}

    	while (true)
	{

		try{thread.sleep(50);}
		catch(InterruptedException e){}

      	if (gclient.running())
	   		continue;
      	if (gclient.input_stream_available())
		{
	   		text = gclient.get_input();
  	   		if (gclient.is_nameslist(text))
   	  			write_list(text.substring(9));
	   		if (gclient.is_directive(text))
	  			processDirective(text.substring(13));
   	   		if (!gclient.is_directive(text) && !gclient.is_nameslist(text))
   	  			display(text);
      	 }
 	}
}

// If directive, deal with it according to the message that is attached
public void processDirective(String text)
{

	String temp;
	int next, temp_id, opp_id;
	temp = text;
	text = text.substring(6);
	char next_char;

	// if the directive is a challenge...

	if (temp.startsWith("chlng"))
	{
	  	next = text.indexOf(',');
	    	temp = text.substring(0,next);
	    	if (!game_on)
		{
	      	opponent_id = Integer.parseInt(temp);
	      	text = text.substring(next+1);
	      	temp = text.substring(0);
	      	opponent_temp = temp.trim();
	      	player = PLAYER2;
	      	other_player = PLAYER1;
	      	challenged = true;
	      	display("You have been asked to Play by "+ temp);
	      	display("hit the 'Play Opponent' button to Play\n");
			acceptwindow accept =
				new acceptwindow(this, "Do You Want to Play ", temp);
  	    	}
        	else
		{
	      	opp_id = Integer.parseInt(temp);
	      	temp_id = id_vector.indexOf(new Integer(opp_id));
			battle_id = id_vector.indexOf(new Integer(opp_id));
   	      	gclient.send_stream("!!directive!!mssge,busy|"+Integer.toString(temp_id+1)+"|");
	    	}
	}


	// if the directive is a message...
	if(temp.startsWith("mssge"))
	{
	  	if (text.startsWith("uid"))
		{
	    	  	temp = text.substring(4);
	    	  	personal_id = Integer.parseInt(temp.trim());
	  	}
	  	if (text.startsWith("busy"))
	    	   display ("That player is currently playing a game...\n");
	  	if (text.startsWith("surrender"))
		{
	    	   display("Your opponent has surrendered\n");
   	    	   game_on = false;
	  	}
	}

	// if directive is an accept challenge...
	if(temp.startsWith("accpt") && !challenged)
	{
	  	next = text.indexOf(',');
	  	temp = text.substring(0,next);
	  	temp_id = Integer.parseInt(temp.trim());
	  	if(temp_id == opponent_id)
		{
	    	   	text = text.substring(next+1);
	    	   	game_on = true;
	    	   	player = PLAYER1;
	    	   	other_player = PLAYER2;
	    	   	challenged = false;
	    	   	display("GAME ON!! you go first\n");
			mygame = new game(myapplet, base, this, true, gameimage);

	  	}
	}

	// if directive is a move
	if(temp.startsWith("pmove"))
	{
	  	next = text.indexOf(',');
	  	temp = text.substring(0,next);
		move_received = true;
		nextMoveBuffer = temp;
		mygame.set_opponent_move(nextMoveBuffer); // calls game method
	}
}

public void quitWindow ()
{
   int index;

   	display("Preparing to log off.\n");
   	if (game_on)
	{
    		index = id_vector.indexOf(new Integer(opponent_id));
    		gclient.send_stream("!!directive!!mssge,surrender|"+Integer.toString(index+1)+"|");
   	}
   	gclient.cleanup();
   	dispose();
}

//******************************************************************
// put the unique id's into id_vector and names into user_list
public void write_list(String list)
{
  	int i, next, n;
  	int temp_id;

  	user_list.delItems( 0, user_list.countItems() -1 );
  	user_list.clear();
  	id_vector.removeAllElements();
  	for (i=0;i<list.length();i++)
	{
    	  	n = list.indexOf('~',i);
    	  	next = list.indexOf('|',i);
    	  	if (next >= list.length() || next == -1)
      		break;
    	  	temp_id = Integer.parseInt(list.substring(i,n));
    	  	id_vector.addElement(new Integer(temp_id));

    	  	user_list.addItem(list.substring(n+1,next));
    	  	i = next;
  	}
	//user_list.reshape(258,116,99,176);
}

// display the text to the output area of the screen
public void display(String s)
{
  	try{thread.sleep(100);}catch(InterruptedException e){}
  	textArea.appendText(s);
}

// event handler for GUI components
public boolean handleEvent(Event evt)
{
 	int index, storage;

	// when you double-click on a user name in the user_list
  	if (evt.id == Event.ACTION_EVENT && evt.target == user_list && !game_on)
	{
    		index = user_list.getSelectedIndex();
     		opponent_id = ((Integer)id_vector.elementAt(index)).intValue();
     		if (opponent_id != personal_id)
		{
       		display("Challenging "+ (String)evt.arg + " to Internet game!\n");
       		gclient.send_stream("!!directive!!chlng,"+Integer.toString(personal_id)+"|"+Integer.toString(index+1)+"|");
     		}
        	else
			display("You cannot challenge yourself.\n");
  	}

	// when you perform an action while you are connected
  	if (evt.id == Event.ACTION_EVENT && gclient.is_connected())
	{
    		if (gclient.stream_down())
		{
      		display("A socket error has occured, you are not connected.\n");
      		return super.handleEvent(evt);
    		}

    		if (evt.target == textField)
		{ 	// if want to send a message to the other player
			String textstream = textField.getText();
      		textField.setText("");
      		gclient.send_stream(textstream);
    		}

    	  }
  	return super.handleEvent(evt);
}

public void stop()
{

  	int index;
  	display("Preparing to log off.\n");
  	if (game_on)
	{
    		index = id_vector.indexOf(new Integer(opponent_id));
    		gclient.send_stream("!!directive!!mssge,surrender|"+Integer.toString(index+1)+"|");
  	}
  	gclient.cleanup();
}

//******************************************************************
//	methods to interact with your game class
//	game class calls this to send a move to other player
//******************************************************************
public void sendMove(String text)
{
   	int index;

   	index = id_vector.indexOf(new Integer(opponent_id));
   	gclient.send_stream("!!directive!!pmove," +text+ "|" +Integer.toString(index +1) +"|");
}

public void acceptyes()
{
		int index;

		System.out.println ("accept yes");
		// when you hit the Play Opponent button
   		display("Opponent ready to Play! You will move second.\n");
   		index = id_vector.indexOf(new Integer(opponent_id));
 System.out.println("opponent id is " + opponent_id);
  		gclient.send_stream("!!directive!!accpt,"+Integer.toString(personal_id)+"|"+Integer.toString(index+1)+"|");
   		challenged = false;
   		game_on = true;
		mygame = new game(myapplet, base, this, false, gameimage);
}
} // end class

class acceptwindow extends Frame
{
	private clientwindow parent;
	private Panel buttonPanel;
	private Button acceptyes;
	private Button acceptno;
	private Label user_label;

	public acceptwindow(clientwindow parent, String wintitle, String User)
	{
		super(wintitle);
		this.parent = parent;
		user_label = new Label("You have been asked to play with " + User);
		buttonPanel = new Panel();
		acceptyes = new Button("Play Opponent");
		acceptno = new Button("Don't Play Opponent");

		//Add button to panel and panel to window
		setLayout(new FlowLayout());
		buttonPanel.setLayout(new GridLayout(7,1));
		buttonPanel.add(user_label);
		buttonPanel.add(acceptyes);
		buttonPanel.add(acceptno);
		add(buttonPanel);

		//Size window to preferred size
		this.setSize(300, 300);
		this.show();
	}//end loginwindow


	//  uses the jdk1.0.2 event handler...
	public boolean action(Event e, Object arg)
	{
		if(e.target instanceof Button)
		{
			if(e.target == acceptyes)
			{
				if(this.isShowing())
				{
				   	try
					{
						parent.acceptyes();
				   	}
				   	catch(Exception exceptn)
					{
						exceptn.printStackTrace();
						System.out.println("Error:" + exceptn);
				   	}
				   	finally
					{
					 	this.dispose();
				   	}
				}
			}
			if(e.target == acceptno)
			{
				this.dispose();
			}

		}
		return true;
	} //end action(Event, Object)
}//end class definition
